"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : GUC_ErrorLog
Case Name   : 修改参数log_min_duration_statement的值为0
Create At   : 2022/06/09
Owner       : @li-xin12345
Description :
    1.logging_collector设置为on,log_directory设置新的路径，
      设置log_statement的值为all,设置log_duration=on
    2.修改参数log_min_duration_statement的值为0
    3.登录数据库执行时长大于250ms的sql语句，查看日志
    4.登录数据库执行时长小于250ms的sql语句，查看日志
    5.恢复参数
Expect      :
    1.设置成功
    2.修改成功
    3.日志中记录每条完成语句的持续时间
    4.日志中记录每条完成语句的持续时间
    5.恢复成功
History     :
"""
import os
import re
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from testcase.utils.Constant import Constant


class ErrorLog(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.primary_root = Node('PrimaryRoot')
        self.common = Common()
        self.constant = Constant()
        self.table_name = 't_errorlog_case0070'
        self.dir_new = os.path.join(macro.PG_LOG_PATH, 'pg_errorlog_case0070')
        self.collector = 'logging_collector'
        self.collector_default = self.common.show_param(self.collector)
        self.log_dir = 'log_directory'
        self.log_dir_default = self.common.show_param(self.log_dir)
        self.log_statement = 'log_statement'
        self.log_statement_default = self.common.show_param(self.log_statement)
        self.log_duration = 'log_duration'
        self.log_duration_default = self.common.show_param(self.log_duration)
        self.log_min = 'log_min_duration_statement'
        self.log_min_default = self.common.show_param(self.log_min)

    def test_error_log(self):
        text = '-----step1:logging_collector设置为on,log_directory设置新的路径，' \
               '设置log_statement的值为all,设置log_duration=on;expect:设置成功-----'
        self.logger.info(text)
        if 'on' != self.collector_default:
            result = self.primary_sh.execute_gsguc(
                'set', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.collector}=on')
            self.assertTrue(result, '执行失败' + text)
            restart_res = self.primary_sh.restart_db_cluster()
            self.assertTrue(restart_res, '执行失败' + text)
        show_msg = self.common.show_param(self.collector)
        self.assertEquals(show_msg, 'on', '执行失败' + text)

        if self.dir_new != self.log_dir_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_dir}=\'{self.dir_new}\'')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.log_dir)
        self.assertEquals(show_msg, self.dir_new, '执行失败' + text)
 
        if 'all' != self.log_statement_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_statement}=all')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.log_statement)
        self.assertEquals(show_msg, 'all', '执行失败' + text)

        if 'on' != self.log_duration_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_duration}=on')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.log_duration)
        self.assertEquals(show_msg, 'on', '执行失败' + text)

        text = '-----step2:修改参数log_min_duration_statement的值为0;' \
               'expect:修改成功-----'
        self.logger.info(text)
        if '0' != self.log_min_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_min}=0')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.log_min)
        self.assertEquals(show_msg, '0', '执行失败' + text)

        text = '-----step3:登录数据库执行时长大于250ms的sql语句，查看日志;' \
               'expect:日志中记录每条完成语句的持续时间-----'
        self.logger.info(text)
        sql_cmd = f"create table {self.table_name}(id int,name char(5));" \
            f"insert into {self.table_name} " \
            f"values(generate_series(1,500000),'abc');"
        sql_msg = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_msg)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS and
                      self.constant.INSERT_SUCCESS_MSG,
                      sql_msg, '执行失败' + text)
        shell_cmd = f'''ls -t {self.dir_new} '''
        self.logger.info(shell_cmd)
        logfile = os.path.join(self.dir_new,
                               self.primary_root.sh(shell_cmd).result())
        self.logger.info(logfile)
        tail_cmd = f'tail -n 10 {logfile} '
        self.logger.info(tail_cmd)
        tail_msg = self.primary_node.sh(tail_cmd).result()
        self.logger.info(tail_msg)
        self.assertIn(f"LOG:  statement: create table "
                      f"{self.table_name}(id int,name char(5));" and
                      f"LOG:  statement: insert into {self.table_name} "
                      f"values(generate_series(1,500000),'abc');",
                      tail_msg, '执行失败' + text)
        expect = "LOG:  duration: .* ms, queryid .*, unique id .*"
        search_res = re.search(expect, tail_msg, re.S)
        self.assertIsNotNone(search_res, '执行失败' + text)

        text = '-----step4:登录数据库执行时长小于250ms的sql语句，查看日志;' \
               'expect:日志中记录每条完成语句的持续时间-----'
        self.logger.info(text)
        sql_cmd = f"insert into {self.table_name} " \
            f"values(generate_series(1,50000),'dd');"
        sql_msg = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_msg)
        self.assertIn(self.constant.INSERT_SUCCESS_MSG,
                      sql_msg, '执行失败' + text)
        tail_cmd = f'tail -n 5 {logfile} '
        self.logger.info(tail_cmd)
        tail_msg = self.primary_node.sh(tail_cmd).result()
        self.logger.info(tail_msg)
        self.assertIn(f"LOG:  statement: insert into {self.table_name} "
                      f"values(generate_series(1,50000),'dd');",
                      tail_msg, '执行失败' + text)
        expect = "LOG:  duration: .* ms, queryid .*, unique id .*"
        search_res = re.search(expect, tail_msg, re.S)
        self.assertIsNotNone(search_res, '执行失败' + text)

    def tearDown(self):
        text = '-----step5:恢复参数;expect:恢复成功-----'
        self.logger.info(text)
        sql_cmd = f"drop table {self.table_name};"
        sql_msg = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_msg)

        collector_current = self.common.show_param(self.collector)
        if collector_current != self.collector_default:
            result = self.primary_sh.execute_gsguc(
                'set', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.collector}={self.collector_default}')
            self.logger.info(result)
            restart_res = self.primary_sh.restart_db_cluster()
            self.logger.info(restart_res)
        show_collector = self.common.show_param(self.collector)

        log_dir_current = self.common.show_param(self.log_dir)
        if log_dir_current != self.log_dir_default:
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_dir}=\'{self.log_dir_default}\'')
            self.logger.info(result)
        show_log_dir = self.common.show_param(self.log_dir)

        log_statement_current = self.common.show_param(self.log_statement)
        if self.log_statement_default != log_statement_current:
            self.guc_result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_statement}={self.log_statement_default}')
        show_log_statement = self.common.show_param(self.log_statement)

        log_duration_current = self.common.show_param(self.log_duration)
        if log_duration_current != self.log_duration_default:
            self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_duration}=\'{self.log_duration_default}\'')
        show_log_duration = self.common.show_param(self.log_duration)

        log_min_current = self.common.show_param(self.log_min)
        if log_min_current != self.log_min_default:
            self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_min}=\'{self.log_min_default}\'')
        show_log_min = self.common.show_param(self.log_min)
        self.logger.info('-----断言tearDown-----')
        self.assertIn(self.constant.TABLE_DROP_SUCCESS,
                      sql_msg, '执行失败' + text)
        self.assertEquals(show_collector, self.collector_default, '执行失败' + text)
        self.assertEquals(show_log_dir, self.log_dir_default, '执行失败' + text)
        self.assertEquals(show_log_statement, self.log_statement_default,
                          '执行失败' + text)
        self.assertEquals(show_log_duration, self.log_duration_default,
                          '执行失败' + text)
        self.assertEquals(show_log_min, self.log_min_default, '执行失败' + text)
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
